/**
 * 高阶函数 (HOF) Hight-Order-Function
 *    下面两种情况满足一种即可。
 *    1. 接收的参数是一个函数的函数，可以称为高阶函数
 *    2. 返回值是一个函数的函数，可以称为高阶函数
 *
 *    setTimeout、Promise、arr.filter、arr.map、arr.find、arr.findIndex
 *    arr.reduce ...
 *
 * 高阶组件 (HOC) Hight-Order-Component
 *    特点：
 *    1. 本质上是一个函数
 *    2. 接收的参数是一个组件
 *    3. 返回一个组件
 */

import React from "react";
import ReactDOM from "react-dom/client";

function Button(props) {
  function log() {
    console.log("点击了");
  }

  return <button onClick={log}>{props.children}</button>;
}

function Box(props) {
  function log() {
    console.log("点击了");
  }
  return (
    <div
      style={{ width: "100px", height: "100px", backgroundColor: "red" }}
      onClick={log}
    >
      {props.children}
    </div>
  );
}

// 上面的 Button 与 Box 组件，都有 log 打印日志的功能。并且我们可以思考一下。
// 如果这个log的功能，在很多组件中都要去实现的话，就要写很多次。比较麻烦。
// 这时就可以使用高阶组件的功能。把log功能抽离出来。
function Button1(props) {
  return <button {...props}>{props.children}</button>;
}

function Box1(props) {
  return (
    <div
      style={{ width: "100px", height: "100px", backgroundColor: "red" }}
      {...props}
    >
      {props.children}
    </div>
  );
}

function Ppp(props) {
  return <button {...props}>{props.children}</button>;
}

/**
 * 给组件增加了一个 onClick 的事件上去，且这个事件，点击输入一段 log
 */
function hlog(Component) {
  function log() {
    console.log("点击了");
  }
  return function (props) {
    console.log(props);
    const a = { ...props, onClick: log };
    // return <Button1>点我</Button1>;
    // return <Component title={props.title}>{props.children}</Component>;
    return <Component {...a}></Component>;
  };
}

const NewButton1 = hlog(Button1);
const NewBox1 = hlog(Box1);
const NewPpp = hlog(Ppp);

class App extends React.Component {
  render() {
    return (
      <div>
        <h1>App</h1>
        <NewButton1 id="iid" title="123">
          点我 - NewButton1
        </NewButton1>
        <NewBox1>点我 - NewBox1</NewBox1>
        <NewPpp>ppp</NewPpp>
        <hr />

        <Button>点我</Button>
        <Box>box1</Box>
      </div>
    );
  }
}

const root = ReactDOM.createRoot(document.querySelector("#root"));
root.render(<App />);
